﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Collections.Observable.DebugViews;

namespace System.Collections.Observable
{
    [DebuggerTypeProxy(typeof(ObservableListBaseDebugView<,>))]
    [DebuggerDisplay("Count = {Count}")]
    [Serializable]
    public class ObservableListBase<TValue, TList> : ObservableCollectionBase<TValue, TList>, IObservableList<TValue> 
          where TList: IList<TValue>
        
    {
        public ObservableListBase(TList list):
            base(list)
        {}

        #region IList<TValue> interface implementation

        // Summary:
        //     Gets or sets the element at the specified index.
        //
        // Parameters:
        //   index:
        //     The zero-based index of the element to get or set.
        //
        // Returns:
        //     The element at the specified index.
        //
        // Exceptions:
        //   System.ArgumentOutOfRangeException:
        //     index is not a valid index in the System.Collections.Generic.IList<T>.
        //
        //   System.NotSupportedException:
        //     The property is set and the System.Collections.Generic.IList<T> is read-only.
        public TValue this[int index] 
        {
            get
            {
                return InternalCollection[index];
            }
            set
            {
                TValue oldItem = InternalCollection[index];                
                InternalCollection[index] = value;

                OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, value, oldItem, index) );
            }
        }

        // Summary:
        //     Determines the index of a specific item in the System.Collections.Generic.IList<T>.
        //
        // Parameters:
        //   item:
        //     The object to locate in the System.Collections.Generic.IList<T>.
        //
        // Returns:
        //     The index of item if found in the list; otherwise, -1.
        public int IndexOf(TValue item)
        {
            return InternalCollection.IndexOf(item);
        }

        //
        // Summary:
        //     Inserts an item to the System.Collections.Generic.IList<T> at the specified
        //     index.
        //
        // Parameters:
        //   index:
        //     The zero-based index at which item should be inserted.
        //
        //   item:
        //     The object to insert into the System.Collections.Generic.IList<T>.
        //
        // Exceptions:
        //   System.ArgumentOutOfRangeException:
        //     index is not a valid index in the System.Collections.Generic.IList<T>.
        //
        //   System.NotSupportedException:
        //     The System.Collections.Generic.IList<T> is read-only.
        public void Insert(int index, TValue item)
        {
            InternalCollection.Insert(index, item);

            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index) );
        }

        //
        // Summary:
        //     Removes the System.Collections.Generic.IList<T> item at the specified index.
        //
        // Parameters:
        //   index:
        //     The zero-based index of the item to remove.
        //
        // Exceptions:
        //   System.ArgumentOutOfRangeException:
        //     index is not a valid index in the System.Collections.Generic.IList<T>.
        //
        //   System.NotSupportedException:
        //     The System.Collections.Generic.IList<T> is read-only.
        public void RemoveAt(int index)
        {
            TValue oldValue = InternalCollection[index];
            InternalCollection.RemoveAt(index);

            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, oldValue, index));
        }

        #endregion
    }
}
